<?php
/*
 * @Author: CHINAKAIYUAN<sunkaiyuan@namenode.cn>
 * @Date: 2022-02-04 16:53:56
 * @LastEditTime: 2023-11-11 15:43:40
 * @LastEditors: 孙开源 && sunkaiyuan@namenode.cn
 * @Description: 
 */

namespace App\Http\Services\Pro;


use App\Http\Services\Service;

use App\Repositories\ProPlanRepository;
use App\Repositories\ProPlanStorageRepository;
use App\Repositories\ProPotRawSendRepository;
use App\Repositories\ProPotRepository;
use App\Repositories\ProProcessesPassRepository;
use App\Repositories\ProProcessesRepository;
use App\Repositories\ProPotVerifyRepository;
use App\Repositories\ProProcessesWipRepository;
use App\Repositories\QaAbnormalRepository;
use Illuminate\Support\Facades\DB;

/**
 * @property ProPotRepository $repository
 * @property ProPlanRepository $pro_plan
 * @property ProPotRawSendRepository $raw_send
 * @property ProProcessesRepository $process
 * @property ProProcessesPassRepository $process_pass
 * @property ProPotVerifyRepository $verify
 */
class PotService extends Service
    {

    public function boot(
        ProPotRepository $repository,
        ProPlanRepository $pro_plan,
        // ProPotRawDetailRepository $pot_raw, //大货明细
        ProPotRawSendRepository $raw_send,
        //出库单
        ProProcessesPassRepository $process_pass,
        ProProcessesRepository $process,
        ProPotVerifyRepository $verify

    ) {
        $this->repository   = $repository;
        $this->pro_plan     = $pro_plan;
        $this->raw_send     = $raw_send;
        $this->process_pass = $process_pass;
        $this->process      = $process;
        $this->verify       = $verify;
        }

    protected function saveOqa()
        {
        return $this->repository->saveOqa();
        }
    public function oqaList()
        {
        return $this->repository
            ->setRelation([
                "material",
                "verifor",
                "oqa" => ['machine', 'creator']
            ])
            ->condition(request())
            ->getGrid();
        }
    public function list()
        {
        // DB::enableQueryLog();
        $data = $this->repository->condition(request())->getGrid();
        // dd(DB::getQueryLog());

        return $data;
        }

    public function printReport()
        {
        $data = [];
        if (request('name') == '配料单') {
            $data = $this->repository->getReport($this->getRequestIds());
            }
        else if (request('name') == '流转卡')
            $data = $this->pro_plan->getReport($this->getRequestIds());
        else {
            $data = $this->repository->getAddRawReport($this->getRequestIds());
            }
        return $data;
        }
    public function OnPrintEnd()
        {
        if (request('name') != '配料单') {
            return $this->repository->whereIn("id", $this->getRequestIds())->get()->filter(function ($pot)
                {
                $pot->isprint = $pot->isprint + 1;
                $pot->save();
                });
            }
        }
    protected function addVerify()
        {
        return $this->repository->whereIn("id", $this->getRequestIds())->get()->filter(function ($pot)
            {
            $this->verify->create(['pro_pot_id' => $pot->id, 'dyelot' => $pot->dyelot])->save();
            $pot->count_verify = $this->verify->wherePro_pot_id($pot->id)->count();
            $pot->verifor_id   = auth()->user()->employee_id;
            $pot->save();
            });
        }
    public function getRoute($id = null)
        {
        $pro_plan = $this->repository->whereId($id ?? request('id'))->first()?->pro_plan;
        //流程中
        $max = $pro_plan?->max(function ($plan)
            {
            return $plan->process_route->details->count();
            });

        return $pro_plan?->map(function ($v) use ($max)
            {
            $route = $v->process_route;
            if ($route->details->count() == $max) {
                return $route->details()->with(["process" => ["pro_dept"]])->get();
                }
            })->first();
        }
    public function emergency($emergency_id)
        {
        return $this->repository->whereIn("id", $this->getRequestIds())->get()->filter(function ($pot) use ($emergency_id)
            {
            if ($pot->emergency_id != $emergency_id) {
                $pot->emergency_id = $emergency_id;
                $pot->save();

                $pot->pro_plan->filter(function ($plan) use ($emergency_id)
                    {
                    $plan->emergency_id = $emergency_id;

                    $plan->save();
                    $order = $plan->order;
                    if ($order) {
                        $order->emergency_id = $emergency_id;
                        $order->save();
                        }
                    });
                }
            });
        }

    public function verifyList()
        {
        return $this->repository->with(['verify' => ['creator']])->where("id", request("pro_pot_id"))->first()->verify;
        }
    protected function saveDyePlan()
        {
        $data = request()->toArray();

        $data['dyelot']     = $this->repository->getDyelot($data['loom_id'], $data['potdate']);
        $data['process_id'] = $this->process->whereCode("JH")->value("id");
        $data['raw']        = array_map(function ($item)
            {
            $item['new_quantity'] = $item['quantity'];
            $item['new_rate'] = $item['rate'];
            $item['new_cost'] = $item['cost'];
            return $item;
            }, $data['raw']);
        //保存排缸
        $gdata            = $this->saveRaw($data);
        $is_export        = $this->updatePlan($gdata, $data['plan_ids']);
        $gdata->is_export = $is_export;
        $gdata->save();
        $this->updateYarn($gdata);
        }
    protected function removeDyePlan()
        {

        return $this->repository->whereIn("id", $this->getRequestIds())->get()->filter(function ($pot)
            {
            if ($pot->is_kk == 1) {
                fail("已开卡！请先退回开卡！");
                }

            $plans = $pot->pro_plan;
            $plans->filter(function ($plan)
                {
                $plan->dyelot       = "";
                $plan->pro_pot_id   = 0;
                $plan->process_id   = 0;
                $plan->pro_quantity = $plan->plan_quantity;
                $plan->save();
                });

            //删除大货单
            $pot->raw->filter(function ($raw)
                {
                $raw->delete();
                });
            //删除过数记录
            $pot->process_pass->filter(function ($pass)
                {
                $pass->delete();
                });
            //删除WIP记录
            $pot->wip->filter(function ($wip)
                {
                $wip->delete();
                });
            return $pot->delete();
            });
        }

    protected function save()
        {
        $data = request()->toArray();

        $data['raw']   = array_map(function ($item)
            {
            $item['new_quantity'] = $item['quantity'];
            $item['new_rate'] = $item['rate'];
            $item['new_cost'] = $item['cost'];
            return $item;
            }, $data['raw']);
        $data['is_kk'] = 1;
        //保存排缸
        $gdata = $this->saveRaw($data);
        //创建染化料发货单
        $this->createRaw($gdata);
        //创建WIP库存
        $gdata->pro_plan->filter(function ($v)
            {
            $this->process_pass->init($v);
            });
        return $data;
        }
    private function updateRaw($data)
        {
        $gdata = $this->repository->whereId($data['id'])->first();
        //换缸，重新计算染化料
        if ($data['bath_qty'] != $gdata['bath_qty']) {
            $is_edit = true;
            $gdata->raw_send->filter(function ($raw)
                {
                //取消出库
                $this->raw_send->nooutStorage($raw);
                //删除单据明细
                $raw->details->filter(function ($detail)
                    {
                    $detail->delete();
                    });
                //删除单据
                $raw->delete();
                });
            }
        return $gdata;
        }
    private function updatePlan($gdata, $plan_ids)
        {
        $is_export = 0;
        $this->pro_plan->whereIn("id", $plan_ids)->get()->filter(function ($item, $key) use ($gdata, &$is_export)
            {
            if ($item->is_export == 1)
                $is_export = 1;

            $item->dyelot       = $gdata->merge_count > 1 ? ($gdata->dyelot . "-" . ($key + 1)) : $gdata->dyelot;
            $item->pro_pot_id   = $gdata->id;
            $item->pro_quantity = 0;
            $item->process_id   = $gdata->process_id;
            $item->save();
            //创建刷卡记录
            });
        return $is_export;
        }
    private function updateYarn($gdata)
        {
        $gdata->pro_plan->filter(function ($v) use ($gdata)
            {
            $pro_yarn = $v->pro_yarn;
            if ($pro_yarn) {
                $pro_yarn->code = $gdata->code;
                $pro_yarn->save();
                }
            });
        }
    private function createRaw($gdata)
        {
        $rawSend = $this->raw_send->createSend($gdata->id, $gdata->material_id, $gdata->dyelot, $gdata->color_id, $gdata->quantity, $gdata->raw->toArray());
        //染化料发货单出库
        $this->raw_send->outStorage($rawSend);
        }

    protected function saveRaw($gdata = null)
        {
        if (isNotEmpty($gdata['id'] ?? "")) {
            $process_id = $this->repository->whereId($gdata['id'])->value("process_id");
            if ($process_id == 14) {
                fail("排缸单已复修！禁止操作！");
                }
            }
        return $this->repository->autosave($gdata ?? request()->toArray(), true, ['raw']);
        }
    public function raw()
        {
        return $this->repository->with(['raw' => ['material', 'uunit', 'ounit']])->whereId(request("pro_pot_id"))->first()->raw;
        }
    private function createYzDyeingPlan($data, $pot)
        {
        $user     = auth()->user();
        $hank     = $pot->pro_plan()->sum("hank");
        $add_data = [
            'order_code'         => '',
            'pro_dept_id'        => 284,//写死车间
            'plan_id'            => '1',
            'order_id'           => 0,
            'department_id'      => $user->department_id,
            'feeding_ratio'      => $data['feeding_ratio'],
            'material_id'        => $data['material_id'],
            'process_route_id'   => 2,
            'lot_name'           => $data['lot_name'],
            'color_id'           => $data['color_id'],
            'loom_id'            => $data['loom_id'],
            'company_id'         => 31,
            'plan_quantity'      => $data['quantity'],
            'pro_quantity'       => $data['quantity'],
            'order_user_id'      => $user->id,
            'outfactory_id'      => 31,
            'classgroup_id'      => 0,
            'auxiliary_quantity' => $data['quantity'] / 25,
            'hank'               => $hank,
            'perhank'            => ($hank / $data['quantity'] * 25),
            'isrepair'           => 1
        ];

        $plan = ProPlanRepository::create($add_data);

        $this->setWipStorageData($pot->wip()->get(), $plan);
        return $plan;
        }
    private function setWipStorageData($wips, $plan)
        {
        $wips->filter(function ($wip) use ($plan)
            {
            ProPlanStorageRepository::create([
                'pro_plan_id'   => $plan->id,
                'material_id'   => $plan->material_id,
                'dyelot'        => $wip->dyelot,
                'lot_id'        => $plan->lot_id,
                'color_id'      => $plan->color_id,
                'company_id'    => 31,
                'mpc_detail_id' => $wip->id,
                'quantity'      => $wip->faultle_quantity,
                'isrepair'      => 1 //复修库存标志
            ]);
            //扣库
            ProProcessesWipRepository::run("subWipStorage", [$wip, $wip->faultle_quantity]);
            });
        }
    private function repairpot($potdata, $form)
        {
        $data = $this->createYzDyeingPlan($form, $potdata);

        $form['location_name'] = "复修";
        $form['company_name']  = "YZ";
        $form['merge_count']   = 1;
        $form['dyelot']        = $this->repository->getDyelot($form['loom_id']);
        $form['process_id']    = $this->process->whereCode("JH")->value("id");

        $form['raw'] = array_map(function ($item)
            {
            $item['new_quantity'] = $item['quantity'];
            $item['new_rate'] = $item['rate'];
            $item['new_cost'] = $item['cost'];
            return $item;
            }, $form['raw']);
        //保存排缸
        $gdata = $this->saveRaw($form);

        $this->updatePlan($gdata, [$data->id]);

        //创建染化料发货单
        $this->createRaw($gdata);
        }
    //复修
    protected function repair()
        {
        $request = request();
        $potdata = $request->potdata;
        $form    = $request->form;


        $pdata = $this->repository->whereId($potdata['id'])->first();

        if ($pdata->process_id == 14) {
            fail("无法复修！已复修！");
            }
        if ($pdata->process_id == 10) {
            fail("进缸之后才可以进复修！已复修！");
            }
        if ($pdata->process_id == 10) {
            fail("进缸之后才可以进复修！已复修！");
            }
        if ($pdata->count_verify == 0) {
            fail("对样之后才可以进复修！已复修！");
            }
        if ($pdata->wip->count() == 0) {
            fail("当前库存已全部入库！无法进复修！");
            }
        $pdata->repairreason_id = $potdata['repairreason_id'];

        $reject_quantity = 0;
        $pdata->wip->filter(
            function ($wip) use (&$reject_quantity)
                {
                $reject_quantity = $reject_quantity + ProProcessesPassRepository::repairSwip($wip);
                }
        );
        //QA 新增
        $pdata->repair_msg_id = QaAbnormalRepository::abnormalCreate($pdata->dyelot, $pdata->material_id, $pdata->color_id, $pdata->pro_plan[0]->lot_id, $potdata['repairreason']['name'] . ";" . $pdata->remark)->id;

        $pdata->rejects_quantity = $reject_quantity;
        $pdata->save();
        //创建开卡
        if (count($request->repairpot) > 0) {
            $this->repairpot($pdata, $form);
            }
        return $pdata;
        }
    protected function norepair()
        {
        return $this->repository->whereIn("id", $this->getRequestIds())->get()->filter(function ($v)
            {
            if ($v->process_id != 14) {
                fail("无法取消复修！该单据未复修！");
                }
            $reject_quantity    = 0;
            $v->repairreason_id = null;
            $v->wip->filter(function ($wip) use (&$reject_quantity)
                {
                $reject_quantity = $reject_quantity + ProProcessesPassRepository::norepairSwip($wip);
                });
            if ($v->rejects_quantity != $reject_quantity) {
                fail("复修次品数量和当前WIP次品数量不一致！WIP库存已被使用，取消复修失败！");
                }
            //QA 删除
            $abn_msg            = $v->repair_msg;
            $abnormal           = $abn_msg->abnormal;
            $abnormal->abncount -= 1;
            $abnormal->abncount == 0 && $abnormal->delete();
            $abn_msg->delete();

            $v->save();
            });
        }
    public function addRawList()
        {
        $res = [];
        $this->raw_send->with(['details' => ['material', 'uunit', 'ounit']])->wherePro_pot_id(request("pro_pot_id"))->whereState(2)->get()->filter(function ($item) use (&$res)
            {
            $item->details->filter(function ($v) use (&$res)
                {
                $res[] = $v;
                });
            });
        return $res;
        }
    /**
     * 整单过数
     * @return mixed 返回最前面流程的WIP，保证不遗留
     * @author sunkaiyuan
     */
    public function wip()
        {

        $data = $this->repository->condition()->first();

        $min_sort  = 999;
        $front_wip = $data->wip()->where("faultle_quantity", ">", 0)->whereIs_scrap(0)->get()->map(function ($v) use (&$min_sort)
            {
            $v->company;
            $v->pro_plan->process_route->details->some(function ($route) use (&$v)
                {
                if ($v->process_id == $route->process_id) {
                    $v['sort'] = $route->sort;
                    }
                });
            if ($v['sort'] < $min_sort) {
                $min_sort = $v['sort'];
                }
            return $v;
            })->where(function ($v) use ($min_sort)
                {
                return $v->sort == $min_sort;
                })->values();

        return $front_wip;
        }
    protected function nosaveDyePlan($ids = null)
        {
        return $this->repository->whereIn("id", $ids ?? $this->getRequestIds())->get()->filter(function ($pot)
            {
            if ($pot->is_kk == 0) {
                fail("已取消了开卡，不用继续取消！");
                }
            if ($pot->raw_send->count() > 1) {
                fail("有加料单！禁止退回！");
                }
            if (($pot->process->code ?? "JH") != 'JH') {
                fail("已刷卡，禁止退回！");
                }

            $pot->raw_send?->filter(function ($raw)
                {
                //取消出库
                $this->raw_send->nooutStorage($raw);
                //删除单据明细
                $raw->details->filter(function ($detail)
                    {
                    $detail->delete();
                    });
                //删除单据
                $raw->delete();
                });
            $pot->is_kk = 0;
            return $pot->save();
            });
        }
    }
